/**
 * @file    gt98xx_drv_gpio.c
 * @author  Giantec-Semi ATE
 * @brief   Source file of GPIO driver module.
 * @version 0.1
 * 
 * @copyright Copyright (c) 2021 Giantec-Semi
 */
#include "gt98xx_drv_gpio.h"

/**
 * @addtogroup GT98xx_DRV
 * @{
 */

/**
 * @addtogroup GPIO_DRV
 * @{
 */

/**
 * @addtogroup GPIO_DRV_Private_Macros
 * @{
 */

/**
 * @def IS_DRV_GPIO_PIN
 * @brief Check if __VALUE__ is GPIO pin type
 */
#define IS_DRV_GPIO_PIN(__VALUE__)        (((__VALUE__) == DRV_GPIO_PIN_0) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_1) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_2) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_3) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_4) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_5) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_6) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_7) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_8) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_9) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_10) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_11) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_12) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_13) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_14) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_15) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_16) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_17) \
                                          || ((__VALUE__) == DRV_GPIO_PIN_18) \
                                          || ((__VALUE__) == DRV_GPIO_ALL))

/**
 * @def IS_DRV_GPIO0_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO0_FUN(__VALUE__)       (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO_DEBUG_O) \
                                          || ((__VALUE__) == GPIO0_SPI1_CLK))

/**
 * @def IS_DRV_GPIO1_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO1_FUN(__VALUE__)       (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO_DEBUG_O) \
                                          || ((__VALUE__) == GPIO1_SPI1_DATA) \
                                          || ((__VALUE__) == GPIO1_SPI1_MOSI))

/**
 * @def IS_DRV_GPIO2_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO2_FUN(__VALUE__)       (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO_DEBUG_O) \
                                          || ((__VALUE__) == GPIO2_SPI1M_CS) \
                                          || ((__VALUE__) == GPIO2_SPI1_MISO))

/**
 * @def IS_DRV_GPIO3_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO3_FUN(__VALUE__)       (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO_DEBUG_O) \
                                          || ((__VALUE__) == GPIO3_SPI1_CS1))
                                          
/**
 * @def IS_DRV_GPIO4_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO4_FUN(__VALUE__)       (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO_DEBUG_O) \
                                          || ((__VALUE__) == GPIO4_SPI2_CLK))

/**
 * @def IS_DRV_GPIO5_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO5_FUN(__VALUE__)       (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO_DEBUG_O) \
                                          || ((__VALUE__) == GPIO5_SPI2_DATA) \
                                          || ((__VALUE__) == GPIO5_SPI2_MOSI))
                                          
/**
 * @def IS_DRV_GPIO6_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO6_FUN(__VALUE__)       (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO_DEBUG_O) \
                                          || ((__VALUE__) == GPIO6_SPI2M_CS) \
                                          || ((__VALUE__) == GPIO6_SPI2_MISO) \
                                          || ((__VALUE__) == GPIO6_TEST_CLK_O))

/**
 * @def IS_DRV_GPIO7_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO7_FUN(__VALUE__)       (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO_DEBUG_O) \
                                          || ((__VALUE__) == GPIO7_SPI2_CS1) \
                                          || ((__VALUE__) == GPIO7_UART_RX))
                                          
/**
 * @def IS_DRV_GPIO8_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO8_FUN(__VALUE__)       (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO_DEBUG_O) \
                                          || ((__VALUE__) == GPIO8_SPI2_CS3) \
                                          || ((__VALUE__) == GPIO8_SPI1_CS3))

/**
 * @def IS_DRV_GPIO9_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO9_FUN(__VALUE__)       (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO_DEBUG_O) \
                                          || ((__VALUE__) == GPIO9_I2C_ADDR_CHG))
                                          
/**
 * @def IS_DRV_GPIO10_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO10_FUN(__VALUE__)      (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO_DEBUG_O) \
                                          || ((__VALUE__) == GPIO10_I2C2S_SCK) \
                                          || ((__VALUE__) == GPIO10_UART_TX))

/**
 * @def IS_DRV_GPIO11_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO11_FUN(__VALUE__)      (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO_DEBUG_O) \
                                          || ((__VALUE__) == GPIO11_I2C2S_SDA) \
                                          || ((__VALUE__) == GPIO11_UART_RX))
                                          
/**
 * @def IS_DRV_GPIO12_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO12_FUN(__VALUE__)      (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO_DEBUG_O) \
                                          || ((__VALUE__) == GPIO12_EXINT2) \
                                          || ((__VALUE__) == GPIO12_XVS))

/**
 * @def IS_DRV_GPIO13_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO13_FUN(__VALUE__)      (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO_DEBUG_O) \
                                          || ((__VALUE__) == GPIO13_EXT_CLK) \
                                          || ((__VALUE__) == GPIO13_SWD))
                                          
/**
 * @def IS_DRV_GPIO14_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO14_FUN(__VALUE__)      (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO_DEBUG_O) \
                                          || ((__VALUE__) == GPIO14_EXINT1) \
                                          || ((__VALUE__) == GPIO14_SWCLK) \
                                          || ((__VALUE__) == GPIO14_PWM_SYNC))

/**
 * @def IS_DRV_GPIO15_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO15_FUN(__VALUE__)      (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO_DEBUG_O) \
                                          || ((__VALUE__) == GPIO15_UART_TX))
                                          
/**
 * @def IS_DRV_GPIO16_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO16_FUN(__VALUE__)      (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO_DEBUG_O) \
                                          || ((__VALUE__) == GPIO16_UART_RX))

/**
 * @def IS_DRV_GPIO17_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO17_FUN(__VALUE__)      (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO17_CHIP_MODE_1))
                                          
/**
 * @def IS_DRV_GPIO18_FUN
 * @brief Check if __VALUE__ is GPIO0 fun type
 */
#define IS_DRV_GPIO18_FUN(__VALUE__)      (((__VALUE__) == GPIO_NOMAL) \
                                          || ((__VALUE__) == GPIO18_CHIP_MODE_2))

/**
 * @def IS_DRV_GPIO_DIR
 * @brief Check if __VALUE__ is GPIO direction type
 */
#define IS_DRV_GPIO_DIR(__VALUE__)        (((__VALUE__) == DRV_GPIO_DIR_IN) \
                                          || ((__VALUE__) == DRV_GPIO_DIR_OUT))

/**
 * @def IS_DRV_GPIO_IS
 * @brief Check if __VALUE__ is GPIO IS type
 */
#define IS_DRV_GPIO_IS(__VALUE__)         (((__VALUE__) == DRV_GPIO_IS_EDGE) \
                                          || ((__VALUE__) == DRV_GPIO_IS_LEVEL))
                                           
/**
 * @def IS_DRV_GPIO_EDGE
 * @brief Check if __VALUE__ is GPIO edge decting type
 */
#define IS_DRV_GPIO_EDGE(__VALUE__)       (((__VALUE__) == DRV_GPIO_IS_SINGLE) \
                                          || ((__VALUE__) == DRV_GPIO_IS_BOTH))
                                           
/**
 * @def IS_DRV_GPIO_OUTMODE
 * @brief Check if __VALUE__ is GPIO output mode
 */
#define IS_DRV_GPIO_OUTMODE(__VALUE__)    (((__VALUE__) == DRV_GPIO_OUTMODE_PUSHPULL) \
                                          || ((__VALUE__) == DRV_GPIO_OUTMODE_OPENDRAIN))
                                          
/**
 * @def IS_DRV_GPIO_SPEED
 * @brief Check if __VALUE__ is GPIO speed type
 */
#define IS_DRV_GPIO_SPEED(__VALUE__)      (((__VALUE__) == DRV_GPIO_SPEED_FAST) \
                                          || ((__VALUE__) == DRV_GPIO_SPEED_SLOW))
                                          
/**
 * @def IS_DRV_GPIO_PULL_DIR
 * @brief Check if __VALUE__ is GPIO pull direction type
 */
#define IS_DRV_GPIO_PULL_DIR(__VALUE__)   (((__VALUE__) == DRV_GPIO_PULL_NO) \
                                          || ((__VALUE__) == DRV_GPIO_PULL_UP) \
                                          || ((__VALUE__) == DRV_GPIO_PULL_DOWN))

/** @} GPIO_DRV_Private_Macros */


/**
 * @addtogroup GPIO_DRV_Exported_Functions
 * @{
 */

/**
 * @fn ErrorStatus DrvGpioDeInit(GpioTypedef* GPIOx)
 * @brief De-initialize GPIO registers
 * 
 * @param[in] GPIOx GPIO instance
 * @return GPIO is de-initialized or not
 * @retval kSuccess GPIO registers are de-initialized
 * @retval kError GPIO registers are not de-initialized
 */
ErrorStatus DrvGpioDeInit(GpioTypedef* GPIOx) {
  ErrorStatus status = kSuccess;
  if (GPIOx == GPIO) {
    CLEAR_BIT(RST_CTL_REG->MCU_BLK_RST, MCU_BLK_RST_GPIO);
    SET_BIT(RST_CTL_REG->MCU_BLK_RST, MCU_BLK_RST_GPIO);
    
    CLEAR_BIT(RST_CTL_REG->MCU_BLK_RST, GLOBAL_SOFT_RST);
    SET_BIT(RST_CTL_REG->MCU_BLK_RST, GLOBAL_SOFT_RST);
  }
  else {
    status = kError;
  }
  return status;
}


/**
 * @fn ErrorStatus DrvGpioInit(GpioTypedef* GPIOx, DrvGpioInitTypedef* gpio_init_struct)
 * @brief Initialize GPIO registers according to the specified parameters in DrvGpioInitTypedef
 * 
 * @param[in] GPIOx GPIO instance
 * @param[in] gpio_init_struct pointer to a DrvGpioInitTypedef structure that contians the 
 *            configuration information for the specified GPIO peripheral 
 * @return GPIO is initialized or not
 * @retval kSuccess GPIO registers are initialized according to gpio_init_struct content
 * @retval kError Problem occured during GPIO registers initialization
 */
ErrorStatus DrvGpioInit(GpioTypedef* GPIOx, DrvGpioInitTypedef* gpio_init_struct) {
  ErrorStatus status = kError;
  
  assert_param(IS_DRV_GPIO_PIN(gpio_init_struct->pin));
  switch (gpio_init_struct->pin){
    case DRV_GPIO_PIN_0:{
      assert_param(IS_DRV_GPIO0_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_1:{
      assert_param(IS_DRV_GPIO1_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_2:{
      assert_param(IS_DRV_GPIO2_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_3:{
      assert_param(IS_DRV_GPIO3_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_4:{
      assert_param(IS_DRV_GPIO4_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_5:{
      assert_param(IS_DRV_GPIO5_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_6:{
      assert_param(IS_DRV_GPIO6_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_7:{
      assert_param(IS_DRV_GPIO7_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_8:{
      assert_param(IS_DRV_GPIO8_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_9:{
      assert_param(IS_DRV_GPIO9_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_10:{
      assert_param(IS_DRV_GPIO10_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_11:{
      assert_param(IS_DRV_GPIO11_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_12:{
      assert_param(IS_DRV_GPIO12_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_13:{
      assert_param(IS_DRV_GPIO13_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_14:{
      assert_param(IS_DRV_GPIO14_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_15:{
      assert_param(IS_DRV_GPIO15_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_16:{
      assert_param(IS_DRV_GPIO16_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_17:{
      assert_param(IS_DRV_GPIO17_FUN(gpio_init_struct->fun));
      break;
    }
    
    case DRV_GPIO_PIN_18:{
      assert_param(IS_DRV_GPIO18_FUN(gpio_init_struct->fun));
      break;
    }
    
    default:
      break;
  }
  assert_param(IS_DRV_GPIO_DIR(gpio_init_struct->dir));
  assert_param(IS_DRV_GPIO_OUTMODE(gpio_init_struct->out_mode));
  assert_param(IS_DRV_GPIO_SPEED(gpio_init_struct->speed));
  assert_param(IS_DRV_GPIO_PULL_DIR(gpio_init_struct->pull_up_down));
  
  DrvSetGpioDir(GPIOx, gpio_init_struct->pin, gpio_init_struct->dir);
  DrvSetGpioOutMode(MCU_IO_CFG, gpio_init_struct->pin, gpio_init_struct->out_mode);
  DrvSetGpioSpeed(MCU_IO_CFG, gpio_init_struct->pin, gpio_init_struct->speed);
  DrvSetGpioPullUpDown(MCU_IO_CFG, gpio_init_struct->pin, gpio_init_struct->pull_up_down);
  DrvSetGpioIOSharing(IO_SHARING_CONTROLLER, gpio_init_struct->pin, gpio_init_struct->function);
  
  status = kSuccess;
  
  return status;
}


/**
 * @fn void DrvGpioStructInit(DrvGpioInitTypedef* gpio_init_struct)
 * @brief Set each @ref DrvGpioInitTypedef field to default value
 * 
 * @param[out] gpio_init_struct pointer to a @ref DrvGpioInitTypedef structure
 *             whose field will be set to default values
 * @return None
 */
void DrvGpioStructInit(DrvGpioInitTypedef* gpio_init_struct) {
  gpio_init_struct->data                  = 0x1;
  gpio_init_struct->pin                   = DRV_GPIO_ALL;
  gpio_init_struct->dir                   = DRV_GPIO_DIR_OUT;
  gpio_init_struct->out_mode              = DRV_GPIO_OUTMODE_PUSHPULL;
  gpio_init_struct->speed                 = DRV_GPIO_SPEED_FAST;
  gpio_init_struct->pull_up_down          = DRV_GPIO_PULL_NO;
}

/** @} GPIO_DRV_Exported_Functions */
/** @} GPIO_DRV */
/** @} GT98xx_DRV */
